import { FileList } from "./components/FileList";
import { FilePicker } from "./components/FilePicker";
import { ScanPanel } from "./components/ScanPanel";
import { SettingsModal } from "./components/SettingsModal";
import { useBugCheck } from "./hooks/useBugCheck";
import { useAutoFix } from "./hooks/useAutoFix";

import { useState, useMemo } from "react";
import type { ChatMessage } from "./types/autoFix";
import { sendChat } from "./lib/api/autoFix";
import { UI_STRINGS } from "./config/strings";
import { STYLES } from "./config/styles";
import { ChatMessageView } from "./components/ChatMessage";
// no markdown rendering for reports anymore

function App() {
  const { files, report, loading, handleFileUpload, runCheck, url, handleUrlChange } = useBugCheck();
  const { result } = useAutoFix();
  const [chatInput, setChatInput] = useState("");
  const [chat, setChat] = useState<ChatMessage[]>([]);
  const [chatLoading, setChatLoading] = useState(false);
  const hasFiles = useMemo(() => files.length > 0, [files]);

  // 检验报告相关状态
  const [validating, setValidating] = useState(false);
  const [settingsOpen, setSettingsOpen] = useState(false);

  // 生成并下载 Word 检验报告
  const handleValidateReport = async () => {
    if (!hasFiles) return;
    setValidating(true);
    try {
      const form = new FormData();
      files.forEach((f) => form.append("files", f));
      const res = await fetch("/api/validate-report?format=word", {
        method: "POST",
        body: form,
      });
      if (!res.ok) throw new Error("下载失败");
      const blob = await res.blob();
      const url = window.URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      // 文件名后缀加日期时间由后端生成，此处留兜底
      a.download = "代码检验报告.docx";
      document.body.appendChild(a);
      a.click();
      a.remove();
      window.URL.revokeObjectURL(url);
    } catch (e) {
      alert((e as Error)?.message ?? "生成/下载失败");
    } finally {
      setValidating(false);
    }
  };

  // 过滤函数（用于“修复此问题”流程）：
  // 同时隐藏第一条用户消息和第一条助手消息，避免首轮提示与模型首句占据视野
  const filterFirstUserAndAssistant = (history: ChatMessage[]): ChatMessage[] => {
    if (!history || history.length === 0) return history;
    let skippedUser = false;
    let skippedAssistant = false;
    const out: ChatMessage[] = [];
    for (const m of history) {
      if (m.role === "user") {
        if (!skippedUser) { skippedUser = true; continue; }
      } else {
        if (!skippedAssistant) { skippedAssistant = true; continue; }
      }
      out.push(m);
    }
    return out;
  };

  return (
    <div className={STYLES.page}>
      {/* 顶部标题栏 */}
      <header className="w-full px-6 py-4 flex items-center justify-between">
        <h1 className={STYLES.title}>{UI_STRINGS.appTitle}</h1>
        <div>
          <button
            className={STYLES.btnSecondary + " px-3 py-1 text-sm"}
            onClick={() => setSettingsOpen(true)}
            title="设置"
          >
            设置
          </button>
        </div>
      </header>
      <SettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} />

      {/* 主体两栏布局，占满可视高度 */}
      <main className="flex-1 min-h-0 px-6 pb-6">
        <div className="grid grid-cols-1 lg:grid-cols-2 gap-4 h-full min-h-0 items-stretch">
          {/* 左侧：上传（上）与检测（下） */}
          <div className="flex flex-col gap-4 h-full min-h-0">
            <div className={STYLES.card}>
              {/* 文件上传：使内容可滚动，避免预览溢出 */}
              <div className="flex-1 min-h-0 overflow-auto pr-3 upload-scrollbar">
                {/* 文件上传控件 */}
                <FilePicker
                  onFileChange={handleFileUpload}
                  onUrlChange={handleUrlChange}
                  urlValue={url}
                />

                {/* 文件列表（带自身最大高度和滚动） */}
                <div className="mt-4">
                  <FileList files={files} url={url} />
                </div>
              </div>
            </div>

            {/* 下方新的扫描面板：放置检测按钮与结果 */}
            <div className="h-full min-h-0">
              <ScanPanel
                files={files}
                url={url}
                runCheck={runCheck}
                loading={loading}
                report={report}
                fixing={chatLoading}
                onFixIssue={(issue) => {
                  const pick = files.filter((f) => {
                    const rel = (f as unknown as { webkitRelativePath?: string }).webkitRelativePath;
                    return f.name === issue.file || (rel && rel.endsWith("/" + issue.file));
                  });
                  const selected = pick.length ? pick : files;
                  const msg = `请修复文件 ${issue.file}${issue.line ? ` 第 ${issue.line} 行` : ""} 的问题：${issue.message}`;
                  setChat((prev) => [...prev, { role: "user", content: msg }]);
                  setChatLoading(true);
                  sendChat(selected, msg, issue)
                    .then((data) => {
                      if (data.chat_history) setChat(filterFirstUserAndAssistant(data.chat_history));
                    })
                    .catch((e) => {
                      console.error("chat send error", e);
                      alert((e as Error)?.message ?? "发送失败");
                    })
                    .finally(() => setChatLoading(false));
                }}
                onValidateReport={handleValidateReport}
                validating={validating}
                scanCompleted={!!report && !loading}
                result={result}
              />
            </div>
          </div>

          {/* 右侧：聊天窗口 */}
          <div className={STYLES.card}>
          <h2 className="text-lg font-semibold mb-3">与修复 AI 对话</h2>
            <div className="border border-gray-200 rounded-md flex-1 min-h-0 flex flex-col">
            <div className="flex-1 overflow-auto p-3 space-y-3 bg-gray-50">
              {chat.length === 0 && (
                <div className="text-sm text-gray-500">暂无对话，选择问题点击“修复此问题”，或直接在下方输入消息与 AI 交谈。</div>
              )}
              {chat.map((m, i) => (
                <ChatMessageView key={i} role={m.role} content={m.content} />
              ))}
            </div>
            <div className="p-2 border-t bg-white flex gap-2">
              <input
                value={chatInput}
                onChange={(e) => setChatInput(e.target.value)}
                placeholder={hasFiles ? "输入要修复的问题或要求" : "请先上传代码文件"}
                className="flex-1 border border-gray-300 rounded px-2 py-1 text-sm text-gray-900 bg-white placeholder:text-gray-500"
                disabled={!hasFiles}
              />
              <button
                className={STYLES.btnPrimary}
                disabled={!hasFiles || !chatInput.trim() || chatLoading}
                onClick={() => {
                  const text = chatInput.trim();
                  if (!text) return;
                  setChatInput("");
                  setChat((prev) => [...prev, { role: "user", content: text }]);
                  setChatLoading(true);
                  sendChat(files, text)
                    .then((data) => {
                      if (data.chat_history) setChat((data.chat_history));
                    })
                    .catch((e) => {
                      console.error("chat send error", e);
                      alert((e as Error)?.message ?? "发送失败");
                    })
                    .finally(() => setChatLoading(false));
                }}
              >
                {chatLoading ? (
                  <span className="inline-flex items-center gap-2">
                    <span className="inline-block w-4 h-4 border-2 border-white/70 border-t-transparent rounded-full animate-spin" />
                    正在生成...
                  </span>
                ) : (
                  "发送"
                )}
              </button>
            </div>
            </div>
          </div>
        </div>
      </main>
    </div>
  );
}

export default App;
